package ar.uba.fi.celdas7568.ciudad;

public class OpinionZona extends Opinion {

	public int caracteristicasTotales;
	
	public int cantidadCoincidenciasDeseables;
	public int cantidadCoincidenciasIndeseables;
	public int cantidadCoincidenciasImprescincibles;
	public int cantidadCoincidenciasInadmisibles;
	
	public int cantidadDisidenciasDeseables;
	public int cantidadDisidenciasIndeseables;
	public int cantidadDisidenciasImprescincibles;
	public int cantidadDisidenciasInadmisibles;
	
	Caracteristicas coincidenciasPorCaracteristica = new Caracteristicas();
	
	
	public void generarOpinion(Zona zona, Personalidad personalidad) {
		caracteristicasTotales=0;
		
		cantidadCoincidenciasDeseables=0;
		cantidadCoincidenciasIndeseables=0;
		cantidadCoincidenciasImprescincibles=0;
		cantidadCoincidenciasInadmisibles=0;
		
		cantidadDisidenciasDeseables=0;
		cantidadDisidenciasIndeseables=0;
		cantidadDisidenciasImprescincibles=0;
		cantidadDisidenciasInadmisibles=0;
		
		this.zona = zona;
		coincidenciasPorCaracteristica.valorMedioTierra = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.valorMedioTierra, personalidad.valoresCaracteristicas.valorMedioTierra, (int)personalidad.relacionCaracteristicas.valorMedioTierra), (int)personalidad.clasificacionCaracteristicas.valorMedioTierra);
		coincidenciasPorCaracteristica.densidadPoblacional = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.densidadPoblacional, personalidad.valoresCaracteristicas.densidadPoblacional, (int)personalidad.relacionCaracteristicas.densidadPoblacional), (int)personalidad.clasificacionCaracteristicas.densidadPoblacional);
		coincidenciasPorCaracteristica.poderAdquisitivo = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.poderAdquisitivo, personalidad.valoresCaracteristicas.poderAdquisitivo, (int)personalidad.relacionCaracteristicas.poderAdquisitivo), (int)personalidad.clasificacionCaracteristicas.poderAdquisitivo);
		coincidenciasPorCaracteristica.suciedad = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.suciedad, personalidad.valoresCaracteristicas.suciedad, (int)personalidad.relacionCaracteristicas.suciedad), (int)personalidad.clasificacionCaracteristicas.suciedad);
		coincidenciasPorCaracteristica.transito = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.transito, personalidad.valoresCaracteristicas.transito, (int)personalidad.relacionCaracteristicas.transito), (int)personalidad.clasificacionCaracteristicas.transito);
		coincidenciasPorCaracteristica.ruido = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.ruido, personalidad.valoresCaracteristicas.ruido, (int)personalidad.relacionCaracteristicas.ruido), (int)personalidad.clasificacionCaracteristicas.ruido);
		coincidenciasPorCaracteristica.comisarias = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.comisarias, personalidad.valoresCaracteristicas.comisarias, (int)personalidad.relacionCaracteristicas.comisarias), (int)personalidad.clasificacionCaracteristicas.comisarias);
		coincidenciasPorCaracteristica.carceles = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.carceles, personalidad.valoresCaracteristicas.carceles, (int)personalidad.relacionCaracteristicas.carceles), (int)personalidad.clasificacionCaracteristicas.carceles);
		coincidenciasPorCaracteristica.subtes = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.subtes, personalidad.valoresCaracteristicas.subtes, (int)personalidad.relacionCaracteristicas.subtes), (int)personalidad.clasificacionCaracteristicas.subtes);
		coincidenciasPorCaracteristica.colectivos = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.colectivos, personalidad.valoresCaracteristicas.colectivos, (int)personalidad.relacionCaracteristicas.colectivos), (int)personalidad.clasificacionCaracteristicas.colectivos);
		coincidenciasPorCaracteristica.escuelas = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.escuelas, personalidad.valoresCaracteristicas.escuelas, (int)personalidad.relacionCaracteristicas.escuelas), (int)personalidad.clasificacionCaracteristicas.escuelas);
		coincidenciasPorCaracteristica.universidades = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.universidades, personalidad.valoresCaracteristicas.universidades, (int)personalidad.relacionCaracteristicas.universidades), (int)personalidad.clasificacionCaracteristicas.universidades);
		coincidenciasPorCaracteristica.casinos = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.casinos, personalidad.valoresCaracteristicas.casinos, (int)personalidad.relacionCaracteristicas.casinos), (int)personalidad.clasificacionCaracteristicas.casinos);
		coincidenciasPorCaracteristica.teatros = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.teatros, personalidad.valoresCaracteristicas.teatros, (int)personalidad.relacionCaracteristicas.teatros), (int)personalidad.clasificacionCaracteristicas.teatros);
		coincidenciasPorCaracteristica.bibliotecas = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.bibliotecas, personalidad.valoresCaracteristicas.bibliotecas, (int)personalidad.relacionCaracteristicas.bibliotecas), (int)personalidad.clasificacionCaracteristicas.bibliotecas);
		coincidenciasPorCaracteristica.cines = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.cines, personalidad.valoresCaracteristicas.cines, (int)personalidad.relacionCaracteristicas.cines), (int)personalidad.clasificacionCaracteristicas.cines);
		coincidenciasPorCaracteristica.bares = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.bares, personalidad.valoresCaracteristicas.bares, (int)personalidad.relacionCaracteristicas.bares), (int)personalidad.clasificacionCaracteristicas.bares);
		coincidenciasPorCaracteristica.parques = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.parques, personalidad.valoresCaracteristicas.parques, (int)personalidad.relacionCaracteristicas.parques), (int)personalidad.clasificacionCaracteristicas.parques);
		coincidenciasPorCaracteristica.plazas = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.plazas, personalidad.valoresCaracteristicas.plazas, (int)personalidad.relacionCaracteristicas.plazas), (int)personalidad.clasificacionCaracteristicas.plazas);
		coincidenciasPorCaracteristica.museos = this.evaluarCaracteristicaSegunClasificacion(Caracteristicas.evaluarCaracteristica(zona.caracteristicas.museos, personalidad.valoresCaracteristicas.museos, (int)personalidad.relacionCaracteristicas.museos), (int)personalidad.clasificacionCaracteristicas.museos);
	}
	
	private int evaluarCaracteristicaSegunClasificacion(boolean evaluacion, int clasificacion){
		caracteristicasTotales++;
		switch (clasificacion) {
		case 0:
			{
			if(evaluacion)
				cantidadCoincidenciasImprescincibles++;
			else
				cantidadDisidenciasImprescincibles++;
			}
			break;
		case 1:
		{
			if(evaluacion)
				cantidadCoincidenciasDeseables++;
			else
				cantidadDisidenciasDeseables++;
			}
			break;
		case 2:
			{
			if(evaluacion)
				cantidadCoincidenciasIndeseables++;
			else
				cantidadDisidenciasIndeseables++;
			}
			break;
		case 3:
			{
			if(evaluacion)
				cantidadCoincidenciasInadmisibles++;
			else
				cantidadDisidenciasInadmisibles++;
			}
		break;
		default:
			break;
		}
		
		if (evaluacion) {
			return 1;
		}else {
			return 0;
		}
	}

	public static OpinionZona obtenerMejorOpinion(OpinionZona mejorOpinion,
			OpinionZona opinion) {
		if(mejorOpinion==null)
			return opinion;
		
		if(mejorOpinion.cantidadCoincidenciasIndeseables < opinion.cantidadCoincidenciasIndeseables)
			return mejorOpinion;
		else{
			if(mejorOpinion.cantidadCoincidenciasIndeseables > opinion.cantidadCoincidenciasIndeseables)
				return opinion;
			else{//es igual
				if(mejorOpinion.cantidadCoincidenciasDeseables > opinion.cantidadCoincidenciasDeseables)
					return mejorOpinion;
				else{
					if(mejorOpinion.cantidadCoincidenciasDeseables < opinion.cantidadCoincidenciasDeseables)
						return opinion;
					else{//es igual
						return mejorOpinion;//elijo una arbitrariamente
					}
				}
			}
		}
	}

	public static OpinionZona obtenerMejorOpinionDesfavorable(
			OpinionZona opinionMenosDesfavorable, OpinionZona opinion) {
		if(opinionMenosDesfavorable==null)
			return opinion;
		
		if(opinionMenosDesfavorable.cantidadDisidenciasImprescincibles + opinionMenosDesfavorable.cantidadCoincidenciasInadmisibles 
				> opinion.cantidadDisidenciasImprescincibles + opinion.cantidadCoincidenciasInadmisibles) {
			return opinion; 
		
		}else if(opinionMenosDesfavorable.cantidadDisidenciasImprescincibles + opinionMenosDesfavorable.cantidadCoincidenciasInadmisibles 
				< opinion.cantidadDisidenciasImprescincibles + opinion.cantidadCoincidenciasInadmisibles) {
			return opinionMenosDesfavorable;	
		
		}else if (opinionMenosDesfavorable.cantidadDisidenciasDeseables + opinionMenosDesfavorable.cantidadCoincidenciasIndeseables 
				> opinion.cantidadDisidenciasDeseables + opinion.cantidadCoincidenciasIndeseables) {
			return opinion;
			
		}else if(opinionMenosDesfavorable.cantidadDisidenciasDeseables + opinionMenosDesfavorable.cantidadCoincidenciasIndeseables 
				< opinion.cantidadDisidenciasDeseables + opinion.cantidadCoincidenciasIndeseables) {
			return opinionMenosDesfavorable;	
		
		}
		
		return opinionMenosDesfavorable;
	}

	public void modificarPersonalidad(Personalidad personalidad) {
		personalidad.clasificacionCaracteristicas.valorMedioTierra = modificarOpinion((int)personalidad.clasificacionCaracteristicas.valorMedioTierra, (int) coincidenciasPorCaracteristica.valorMedioTierra);
		personalidad.clasificacionCaracteristicas.bares = modificarOpinion((int)personalidad.clasificacionCaracteristicas.bares, coincidenciasPorCaracteristica.bares);
		personalidad.clasificacionCaracteristicas.bibliotecas = modificarOpinion((int)personalidad.clasificacionCaracteristicas.bibliotecas, coincidenciasPorCaracteristica.bibliotecas);
		personalidad.clasificacionCaracteristicas.carceles = modificarOpinion((int)personalidad.clasificacionCaracteristicas.carceles, coincidenciasPorCaracteristica.carceles);
		personalidad.clasificacionCaracteristicas.casinos = modificarOpinion((int)personalidad.clasificacionCaracteristicas.casinos, coincidenciasPorCaracteristica.casinos);
		personalidad.clasificacionCaracteristicas.cines = modificarOpinion((int)personalidad.clasificacionCaracteristicas.cines, coincidenciasPorCaracteristica.cines);
		personalidad.clasificacionCaracteristicas.colectivos = modificarOpinion((int)personalidad.clasificacionCaracteristicas.colectivos, coincidenciasPorCaracteristica.colectivos);
		personalidad.clasificacionCaracteristicas.comisarias = modificarOpinion((int)personalidad.clasificacionCaracteristicas.comisarias, coincidenciasPorCaracteristica.comisarias);
		personalidad.clasificacionCaracteristicas.escuelas = modificarOpinion((int)personalidad.clasificacionCaracteristicas.escuelas, coincidenciasPorCaracteristica.escuelas);
		personalidad.clasificacionCaracteristicas.museos = modificarOpinion((int)personalidad.clasificacionCaracteristicas.museos, coincidenciasPorCaracteristica.museos);
		personalidad.clasificacionCaracteristicas.parques = modificarOpinion((int)personalidad.clasificacionCaracteristicas.parques, coincidenciasPorCaracteristica.parques);
		personalidad.clasificacionCaracteristicas.plazas = modificarOpinion((int)personalidad.clasificacionCaracteristicas.plazas, coincidenciasPorCaracteristica.plazas);
		personalidad.clasificacionCaracteristicas.subtes = modificarOpinion((int)personalidad.clasificacionCaracteristicas.subtes, coincidenciasPorCaracteristica.subtes);
		personalidad.clasificacionCaracteristicas.teatros = modificarOpinion((int)personalidad.clasificacionCaracteristicas.teatros, coincidenciasPorCaracteristica.teatros);
		personalidad.clasificacionCaracteristicas.universidades = modificarOpinion((int)personalidad.clasificacionCaracteristicas.universidades, coincidenciasPorCaracteristica.universidades);
		personalidad.clasificacionCaracteristicas.densidadPoblacional = modificarOpinion((int)personalidad.clasificacionCaracteristicas.densidadPoblacional, (int) coincidenciasPorCaracteristica.densidadPoblacional);
		personalidad.clasificacionCaracteristicas.poderAdquisitivo = modificarOpinion((int)personalidad.clasificacionCaracteristicas.poderAdquisitivo, (int) coincidenciasPorCaracteristica.poderAdquisitivo);
		personalidad.clasificacionCaracteristicas.ruido= modificarOpinion((int)personalidad.clasificacionCaracteristicas.ruido, (int) coincidenciasPorCaracteristica.ruido);
		personalidad.clasificacionCaracteristicas.suciedad= modificarOpinion((int)personalidad.clasificacionCaracteristicas.suciedad, (int) coincidenciasPorCaracteristica.suciedad);
		personalidad.clasificacionCaracteristicas.transito= modificarOpinion((int)personalidad.clasificacionCaracteristicas.transito, (int) coincidenciasPorCaracteristica.transito);				
	}

	private int modificarOpinion(int clasificacion, int coincidencia) {	
		switch (clasificacion) {
		case 0: //Imprescindible
			{
				if (coincidencia == 1) {
					return 0; 
				}else {
					return 1; //Si no se cumplió, bajo las expectativas y pasa a deseable
				}
			}
			
		case 1: //Deseable
			{
				if (coincidencia == 1) {
					return 0; //Si se cumplió, se acostumbra a esa característica y pasa a imprescindible
				}else {
					return 1;
				}
			}
			
		case 2: //Indeseable
			{
				if (coincidencia == 1) {
					return 2;
				}else {
					return 3; //Si no se cumplió, se acostumbra a la ausencia de esa característica y pasa a inadmisible
				}
			}
			
		case 3: //Inadmisible
			{
				if (coincidencia == 1) {
					return 2; //Si se cumple baja las expectativas y pasa a indeseable
				}else {
					return 3;
				}
			}
		
		default:
			return 1;
		}
	}

}
